package cc.rengu.igas.mcps.core.realize.impl;/*
 *Create by fuyp on 2020-6-9
 */

import cc.rengu.igas.mcps.common.constant.McpsParamConstant;
import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.realize.EsbRealSttlePaymentService;
import cc.rengu.igas.mcps.core.realize.PosParamDealService;
import cc.rengu.igas.mcps.facade.base.Header;
import cc.rengu.igas.share.common.dao.RoleAcctInfoMapper;
import cc.rengu.igas.share.common.dao.impl.RoleAcctInfoMapperImpl;
import cc.rengu.igas.share.common.entity.RoleAcctInfo;
import cc.rengu.igas.share.core.model.MchntAcctInfo;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.enums.BizStatusEnum;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.util.BeanUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;

import java.util.List;
import java.util.Optional;

public class EsbRealSttlePaymentServiceImpl implements EsbRealSttlePaymentService {
    private RgLogger rglog = RgLog.getLogger(this.getClass().getName());

    @Override
    public void esbRealSettlePayment(MchntOrderInfo mchntOrderInfo, PayOrderInfo payOrderInfo, Header header) throws Exception {
        /*
         * 调用本行实时打款接口
         * 1:插入支付订单表，并更新相关商户订单表字段
         * 如果打款成功设置商户订单表实时清算标识
         * */
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.INST_ID);
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        String mchntNo = mchntOrderInfo.getMchntNo();
        /*获取商户基本信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo) {
            rglog.error("查询商户信息失败<{}>", mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        //获取商户结算账户信息
        List<MchntAcctInfo> mchntAcctInfoList = mchntService.getMchntAcctInfo(instId, mchntNo);
        Optional<MchntAcctInfo> mchntAcctInfoOpt = mchntAcctInfoList.stream().filter(item -> item.getFundType().equals("00")).findFirst();
        if (!mchntAcctInfoOpt.isPresent()) {
            rglog.debug("未查询到结算账户");
            throw new BizException(RespCodeEnum.MCHNT_ACCT_INFO_NOT_EXIST.getRespCode(), RespCodeEnum.MCHNT_ACCT_INFO_NOT_EXIST.getRespDesc());
        }
        MchntAcctInfo mchntAcctInfo = mchntAcctInfoOpt.get();
        /*连锁商户门店非独立清算 获取一级商户号*/
        if ("N".equals(mchntInfo.getIndependentDataFlag()) && "11".equals(mchntInfo.getMchntType())) {
            /*获取一级商户号*/
            mchntNo = mchntInfo.getChainMchntNo();
        }

        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        /*查询D0的内部户和内部户名称*/
        RoleAcctInfoMapper roleAcctInfoMapper = new RoleAcctInfoMapperImpl();
        String roleId = instId + McpsParamConstant.DEFAULT_TOP_INST_ID;
        RoleAcctInfo roleAcctInfo = roleAcctInfoMapper.selectBankRoleAcctInfoBySettleAcctId(header.getInstId(), "DZ_SUBJECT", roleId);
        /*定义订单处理接口*/
        OrderService orderService = new OrderServiceImpl();
        /*定义dubbo服务的接口*/
        DubboService dubboService = new DubboServiceImpl();
        PayOrderInfo realSettlePayOrderInfo = new PayOrderInfo();
        BeanUtil.beanCopy(payOrderInfo, realSettlePayOrderInfo);
        /*交易码*/
        realSettlePayOrderInfo.setTxnNum(header.getTxnNum());
        /*设置原支付的系统流水号*/
        realSettlePayOrderInfo.setSysSeqNum(payOrderInfo.getSysSeqNum());
        /*修改通道标识，通道序号*/
        realSettlePayOrderInfo.setMsgDstId(ChannelEnum.ESB.getChannelType());
        /*设置通道序号*/
        /*设置通到序号*/
        realSettlePayOrderInfo.setDstCallIndex("9");
        realSettlePayOrderInfo.setChannelOrderId(sysNum);
        realSettlePayOrderInfo.setChannelReconKey(realSettlePayOrderInfo.getChannelOrderId());
        /*收款账号*/
        realSettlePayOrderInfo.setPayeeAcctInfo(mchntAcctInfo.getSettleAcctNo());
        /*付款账号*/
        realSettlePayOrderInfo.setPayerAcctInfo(roleAcctInfo.getActualAcct());
        /* 设置支付订单初始状态，在异步程序中处理对应的订单状态*/
        realSettlePayOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        realSettlePayOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        /*设置实时打款金额,商户清算金额 判断是否是收支两线结算模式*/
        if ("1".equals(mchntInfo.getMchntSettleMode().substring(mchntInfo.getMchntSettleMode().length() - 1))) {
            realSettlePayOrderInfo.setOrderAmt(mchntOrderInfo.getRealSettleAmt());
        } else {
            realSettlePayOrderInfo.setOrderAmt(mchntOrderInfo.getMchntSettleAmt());
        }
        realSettlePayOrderInfo.setRealPayAmt(realSettlePayOrderInfo.getOrderAmt());
        realSettlePayOrderInfo.setChannelBizType("0014");
        realSettlePayOrderInfo.setRespCode(null);
        realSettlePayOrderInfo.setRespDesc(null);
        realSettlePayOrderInfo.setSettleDate(null);
        realSettlePayOrderInfo.setChannelSeqNum(null);
        realSettlePayOrderInfo.setDstTxnNum("00010000175500");
        /*插入支付订单表*/
        if (!orderService.registerOrderInfo(null, null, realSettlePayOrderInfo)) {
            /*D0打款失败，通过清算给商户打款*/
            rglog.error("登记支付订单信息失败,instId:<{}>,sysSeqNum:<{}>,mchntOrderId:<{}>,msgDstId:<{}>",
                    payOrderInfo.getInstId(), payOrderInfo.getSysSeqNum(), payOrderInfo.getMchntOrderId(), payOrderInfo.getMsgDstId());
            return;
        }
        xmlTreeUtil.setXmlTreeObjectValue(McpsTreeNodeConstant.D0_REAL_TIME_CLEAR_ORDER_INFO, realSettlePayOrderInfo);

        /*垫资户未配置，继续交易，资金等商户清算周期清算*/
        if (null != roleAcctInfo) {
            //TODO D0实时入账至本行账户
        }
    }

    @Override
    public void esbRealTimeClear(MchntOrderInfo mchntOrderInfo, PayOrderInfo payOrderInfo, Header header) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = header.getInstId();
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        String mchntNo = mchntOrderInfo.getMchntNo();
        /*获取商户基本信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo) {
            rglog.error("查询商户信息失败<{}>", mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        //获取商户结算账户信息
        List<MchntAcctInfo> mchntAcctInfoList = mchntService.getMchntAcctInfo(instId, mchntNo);
        Optional<MchntAcctInfo> mchntAcctInfoOpt = mchntAcctInfoList.stream().filter(item -> item.getFundType().equals("00")).findFirst();
        if (!mchntAcctInfoOpt.isPresent()) {
            rglog.debug("未查询到结算账户");
            throw new BizException(RespCodeEnum.MCHNT_ACCT_INFO_NOT_EXIST.getRespCode(), RespCodeEnum.MCHNT_ACCT_INFO_NOT_EXIST.getRespDesc());
        }
        MchntAcctInfo mchntAcctInfo = mchntAcctInfoOpt.get();
        /*连锁商户门店非独立清算 获取一级商户号*/
        if ("N".equals(mchntInfo.getIndependentDataFlag()) && "11".equals(mchntInfo.getMchntType())) {
            /*获取一级商户号*/
            mchntNo = mchntInfo.getChainMchntNo();
        }
        /*定义订单处理接口*/
        OrderService orderService = new OrderServiceImpl();
        /*定义dubbo服务的接口*/
        DubboService dubboService = new DubboServiceImpl();
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        PayOrderInfo realSettlePayOrderInfo = new PayOrderInfo();
        BeanUtil.beanCopy(payOrderInfo, realSettlePayOrderInfo);
        realSettlePayOrderInfo.setChannelBizType("0007");
        realSettlePayOrderInfo.setRespCode(null);
        realSettlePayOrderInfo.setRespDesc(null);
        realSettlePayOrderInfo.setSettleDate(null);
        realSettlePayOrderInfo.setChannelSeqNum(null);
        /*收款账号*/
        realSettlePayOrderInfo.setPayeeAcctInfo(mchntAcctInfo.getSettleAcctNo());
        /*付款账号*/
        realSettlePayOrderInfo.setPayerAcctInfo(payOrderInfo.getPayeeAcctInfo());
        /*设置原支付的系统流水号*/
        realSettlePayOrderInfo.setSysSeqNum(payOrderInfo.getSysSeqNum());
        /*修改通道标识，通道序号*/
        realSettlePayOrderInfo.setMsgDstId(ChannelEnum.ESB.getChannelType());
        /*设置交易码*/
        realSettlePayOrderInfo.setTxnNum(header.getTxnNum());
        /*设置通道序号*/
        /*设置通到序号*/
        realSettlePayOrderInfo.setDstCallIndex("9");
        /* 设置支付订单初始状态，在异步程序中处理对应的订单状态*/
        realSettlePayOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        realSettlePayOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        realSettlePayOrderInfo.setChannelOrderId(sysNum);
        realSettlePayOrderInfo.setChannelReconKey(realSettlePayOrderInfo.getChannelOrderId());
        realSettlePayOrderInfo.setDstTxnNum("00010000175500");
        /*设置实时打款金额,商户清算金额*/
        /*设置实时打款金额,商户清算金额 判断是否是收支两线结算模式*/
        if ("1".equals(mchntInfo.getMchntSettleMode().substring(mchntInfo.getMchntSettleMode().length() - 1))) {
            realSettlePayOrderInfo.setOrderAmt(mchntOrderInfo.getRealSettleAmt());
        } else {
            realSettlePayOrderInfo.setOrderAmt(mchntOrderInfo.getMchntSettleAmt());
        }
        realSettlePayOrderInfo.setRealPayAmt(realSettlePayOrderInfo.getOrderAmt());
        /*插入支付订单表*/
        if (!orderService.registerOrderInfo(null, null, realSettlePayOrderInfo)) {
            rglog.error("实时清算登记支付订单信息失败,instId:<{}>,sysSeqNum:<{}>,mchntOrderId:<{}>,msgDstId:<{}>",
                    payOrderInfo.getInstId(), payOrderInfo.getSysSeqNum(), payOrderInfo.getMchntOrderId(), payOrderInfo.getMsgDstId());
            throw new BizException(RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc());
        }
        /*订单表插入树中*/
        xmlTreeUtil.setXmlTreeObjectValue(McpsTreeNodeConstant.REAL_TIME_CLEAR_ORDER_INFO, realSettlePayOrderInfo);

        /*查询商户基础信息*/
        /*查询本行内部渠道户*/
        RoleAcctInfoMapper roleAcctInfoMapper = new RoleAcctInfoMapperImpl();
        RoleAcctInfo roleAcctInfoInfo = roleAcctInfoMapper.selectBankRoleAcctInfoBySettleAcctId(header.getInstId(), "BANK_PAYCHNL_SUBJECT", instId + McpsParamConstant.DEFAULT_TOP_INST_ID);
        if (null != roleAcctInfoInfo) {
            //TODO D0实时入账至本行账户
        }
    }
}
